
import requests
import time
import hashlib
import urllib.parse
import base64

from PIL import Image
import cv2
import numpy as np
import os

import ctypes
import platform
import ddddocr

ocr = ddddocr.DdddOcr()
ocr1 = ddddocr.DdddOcr(beta=True)

def generate_sign(params, timestamp):
    """实现签名生成逻辑"""
    #print("\n--------- 加密结束---------------")
    values_str = ''.join(str(v) for v in params.values())
    #print("values_str",values_str)
    keys_str = ','.join(params.keys())
    #print("keys_str",keys_str)
    params['pm'] = keys_str
    sign_str = urllib.parse.quote_plus(values_str + str(timestamp))
    #print("sign_str",sign_str)
    mdsign = hashlib.md5(sign_str.encode()).hexdigest()
    #print("mdsign",mdsign)
    #print("--------- 加密结束---------------\n")
    return mdsign

def query_student_score(uid, verifyCode):
    url = "https://zwfw.moe.gov.cn/eduSearch/prod/moe/verify/studentScore"

    
    # 请求参数
    params = {
        "name": "***",
        "idCard": "***",
        "stuId": "***",
        "uid": uid,
        "verifyCode": verifyCode
    }
    

    # 请求头
    headers = set_headers(params)

    #print("headers",headers)
    #print("params",params)
    
    # 发送请求
    response = requests.post(
        url,
        headers=headers,
        data=params
    )
    json_data = response.json()
    print("\n")
    print("响应结果:",json_data)
    print("\n")
    if "data" in json_data :
        print("\n------------------ 结果打印---------------")
        print("------------------ 姓名：",json_data["data"]["name"])
        print("------------------ 考试级别：",json_data["data"]["level"])
        print("------------------ 考试成绩：",json_data["data"]["score"])
        
        print("------------------ gender：",json_data["data"]["gender"])
        print("------------------ stuId：",json_data["data"]["stuId"])
        print("------------------ idCard：",json_data["data"]["idCard"])
        print("------------------ centId：",json_data["data"]["centId"])
        print("------------------ 结果打印---------------\n")
    elif json_data["code"] == "00":
        print("\n查询不到该学生信息！\n")
    else:
        print("\n")
        print(json_data)
        print("\n")
    return json_data

def set_headers(params):
    timestamp = int(time.time() * 1000)
    prams2 = params.copy()
    sign = generate_sign(prams2, timestamp)
    # print("params",prams2)
    headers = {
        "Host": "zwfw.moe.gov.cn",
        "Connection": "keep-alive",
        "Accept": "*/*",
        "X-Requested-With": "XMLHttpRequest",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36",
        "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
        "Origin": "https://zwfw.moe.gov.cn",
        "Referer": "https://zwfw.moe.gov.cn/mandarin/",
        "Accept-Encoding": "gzip, deflate, br, zstd",
        "Accept-Language": "zh-CN,zh;q=0.9",
        "Cookie": "_abfpc=8ac9c6c983680a8e99f2ec9c9e8894f995092ced_2.0; cna=00f31c0b21f62adb36945baa7546b739",
        "sec-ch-ua": '"Google Chrome";v="137", "Chromium";v="137", "Not/A)Brand";v="24"',
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": '"Windows"',
        "Sec-Fetch-Dest": "empty",
        "Sec-Fetch-Mode": "cors",
        "Sec-Fetch-Site": "same-origin",
        "reqType": "3",
        "rn": str(timestamp),
        "sign": sign,
        "uid":""
    }
    if 'pm' in prams2 and len(prams2['pm'])>0:
        headers['pm'] = prams2['pm']

    # del  params['pm']
    # params.pop('pm', None)
    # print("params",params)
    return headers

def get_verify_code():
    url = "https://zwfw.moe.gov.cn/eduSearch/prod/moe/govVerifyImage"

    # 请求参数
    params = {} 
    
    headers = set_headers(params)

    response = requests.post(url, headers=headers)
    #print(response)
    if response.status_code == 200:
        json_data = response.json()
        #print(json_data)
        if json_data["code"] == "00":
            image_data = json_data["data"]["imageUrl"].split(",")[1]
            with open("verify_code.jpg", "wb") as f:
                f.write(base64.b64decode(image_data))
            return json_data["data"]["uid"]
    return None



def preprocess_image(image_path):
    # 读取图像并转为灰度
    img = cv2.imread(image_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # 中值滤波去噪
    denoised = cv2.medianBlur(gray, 3)
    
    # 自适应阈值二值化
    thresh = cv2.adaptiveThreshold(denoised, 255, 
                                  cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                  cv2.THRESH_BINARY_INV, 11, 2)
    
    # 形态学操作去除噪点
    kernel = np.ones((1, 1), np.uint8)
    processed = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
    
    return processed

def recognize_captcha(image_path):
    #processed_img = preprocess_image(image_path)
    #success, encoded_image_buffer = cv2.imencode('.jpg', processed_img)
    #image_bytes = encoded_image_buffer.tobytes()

    #ocr.set_ranges(6)    
    #result = ocr.classification(image_bytes, png_fix=True, probability=True)
    #s = ""
    #for i in result['probability']:
    #    s += result['charsets'][i.index(max(i))]
    #print("验证码：",s)
    
    
    #ocr1.set_ranges(6)
    #result = ocr1.classification(image_bytes, png_fix=True, probability=True)
    #s = ""
    #for i in result['probability']:
    #    s += result['charsets'][i.index(max(i))]
    #print("验证码：",s)
    
    
    image = open(image_path, "rb").read()
    ocr.set_ranges(6)
    result = ocr.classification(image, probability=True)
    s = ""
    for i in result['probability']:
        s += result['charsets'][i.index(max(i))]
    print("验证码：",s)
    
    
    ocr1.set_ranges(6)
    result = ocr1.classification(image, probability=True)
    s = ""
    for i in result['probability']:
        s += result['charsets'][i.index(max(i))]
    print("验证码：",s)
    return s


def set_window_topmost(window_name):
    if platform.system() == 'Windows':
        hwnd = ctypes.windll.user32.FindWindowW(None, window_name)
        ctypes.windll.user32.SetWindowPos(
            hwnd, -1, 0, 0, 0, 0, 0x0001 | 0x0002)
    else:
        print("非Windows系统需使用wmctrl等工具实现")

def openimg():
    # 获取当前工作目录
    current_dir = os.getcwd()
    img_path = f"{current_dir}\\verify_code.jpg"
    #print(f"当前工作目录: {img_path}")
    
    img = cv2.imread(img_path)  # 读取为BGR格式

    # 创建可调整大小的窗口
    cv2.namedWindow('Window', cv2.WINDOW_NORMAL)
    cv2.resizeWindow('Window', 160, 60)
    cv2.imshow('Window', img) # 显示窗口
    set_window_topmost('Window')

    # 创建可调整大小的窗口
    cv2.namedWindow('ResizableWindow', cv2.WINDOW_NORMAL)

    # 设置窗口尺寸（宽度x高度）
    cv2.resizeWindow('ResizableWindow', 400, 150)
    
    cv2.imshow('ResizableWindow', img)  # 显示窗口
    set_window_topmost('ResizableWindow')
    
    recognize_captcha(img_path)
    
    cv2.waitKey(5000)  # 等待按键关闭
    cv2.destroyAllWindows()

def verify(uid):
    if uid is not None:
        openimg()
        verifyCode = input("请输入验证码：")
        result = query_student_score(uid,verifyCode)
        #print(result)
        if result["code"] == "06" or result["code"] == 500:
            user_input = input("是否继续使用之前验证码Y/N: ")
            if user_input.lower() == 'y' or user_input.lower() == 'Y':
                verify(uid)
            else:
                return
        else:
            return
    else:
        print("\获取验证码失败，请重试！\n")
    return
    
def do():
    print("========================================")
    print("===========普通话成绩查询器=============")
    print("========================================")
    uid = get_verify_code()
    #print("\n验证码：",uid, "\n")
    verify(uid)


def clear_console():
    if platform.system() == 'Windows':
        os.system('cls')
        os.system('cls')
        os.system('cls')
        os.system('cls')
    else:
        os.system('clear')
        os.system('clear')
        os.system('clear')
        os.system('clear')
        

def fordo():
    while True:
        do()
        user_input = input("按回车键继续（输入q退出）: ")
        if user_input.lower() == 'q' or user_input.lower() == 'Q':
            break
        clear_console()



if __name__ == "__main__":
    fordo()
